package com.xbell.dahua.demo.camera.dahua;

import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.NetSDKLib.LLong;
import com.netsdk.lib.NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.netsdk.lib.NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.netsdk.lib.ToolKits;
import lombok.extern.slf4j.Slf4j;

import java.io.File;

/**
 * 登陆接口实现
 * 主要有 ：初始化、登陆、登出功能
 */
@Slf4j
public class LoginModule {

    public static NetSDKLib NET_SDK = NetSDKLib.NETSDK_INSTANCE;

    /**
     * 设备信息
     **/
    public static NetSDKLib.NET_DEVICEINFO_Ex M_DEVICE_INFO_EX = new NetSDKLib.NET_DEVICEINFO_Ex();

    private static boolean B_INIT = false;

    private static boolean B_LOG_OPEN = false;

    /**
     * \if ENGLISH_LANG
     * Init
     * \else
     * 初始化
     * \endif
     */
    public static boolean init(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {
        B_INIT = NET_SDK.CLIENT_Init(disConnect, null);
        NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        String logPath = new File(".").getAbsoluteFile().getParent() + File.separator + "sdk_log" + File.separator + "sdk.log";
        setLog.bSetFilePath = 1;
        System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        setLog.bSetPrintStrategy = 1;
        setLog.nPrintStrategy = 0;

        if (!NET_SDK.CLIENT_LogOpen(setLog)){
            System.err.println("Open SDK Log Failed!!!");
        }

        if (!B_INIT) {
            log.warn("Initialize SDK failed");
            return false;
        }
        // 设置断线重连回调接口，设置过断线重连成功回调函数后，当设备出现断线情况，SDK内部会自动进行重连操作
        // 此操作为可选操作，但建议用户进行设置
        NET_SDK.CLIENT_SetAutoReconnect(haveReConnect, null);

        //设置登录超时时间和尝试次数，可选
        //登录请求响应超时时间设置为5S
        int waitTime = 5000;
        //登录时尝试建立链接1次
        int tryTimes = 1;
        NET_SDK.CLIENT_SetConnectTime(waitTime, tryTimes);

        // // GDPR使能全局开关
        NET_SDK.CLIENT_SetGDPREnable(true);

        // 设置更多网络参数，NET_PARAM的nWaittime，nConnectTryNum成员与CLIENT_SetConnectTime
        // 接口设置的登录设备超时时间和尝试次数意义相同,可选
        NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
        // 登录时尝试建立链接的超时时间
        netParam.nConnectTime = 10000;
        // 设置子连接的超时时间
        netParam.nGetConnInfoTime = 3000;
        NET_SDK.CLIENT_SetNetworkParam(netParam);

        return true;
    }

    /**
     * \if ENGLISH_LANG
     * CleanUp
     * \else
     * 清除环境
     * \endif
     */
    public static void cleanup() {
        if (B_LOG_OPEN) {
            NET_SDK.CLIENT_LogClose();
        }

        if (B_INIT) {
            NET_SDK.CLIENT_Cleanup();
        }
    }

    /**
     * \if ENGLISH_LANG
     * Login Device
     * \else
     * 登录设备
     * \endif
     */
    public static LLong login(String ip, int port, String user, String pwd) {
        //入参
        NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstInParam.nPort = port;
        pstInParam.szIP = ip.getBytes();
        pstInParam.szUserName = user.getBytes();
        pstInParam.szPassword = pwd.getBytes();
        //出参
        NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstOutParam.stuDeviceInfo = M_DEVICE_INFO_EX;
        LLong  loginHandle = NET_SDK.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
        if (loginHandle.longValue() == 0) {
            log.error("Login,IP:{},Port:{},Msg:{}", ip, port, ToolKits.getErrorCodePrint());
        } else {
            log.info("Login Success,IP:{}", ip);
        }
        return loginHandle;
    }

    /**
     * \if ENGLISH_LANG
     * Logout Device
     * \else
     * 登出设备
     * \endif
     */
    public static boolean logout(LLong loginHandle) {
        if (loginHandle.longValue() == 0) {
            return false;
        }

        boolean bRet = NET_SDK.CLIENT_Logout(loginHandle);
        if (bRet) {
            loginHandle.setValue(0);
        }

        return bRet;
    }
}
